package com.yizisu.basemvvm.utils

import com.yizisu.basemvvm.okHttpClient
import okhttp3.OkHttpClient
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.lang.NullPointerException

/**
 *
 * 网络工具类
 */

/**
 * 创建一个service
 */
object RetrofitHelper {
    private var retrofit: Retrofit? = null
    private lateinit var api: Any
    /**
     * 默认的创建网络的请求，数据会转为Bean
     */
    @Suppress("UNCHECKED_CAST")
    fun <T> createService(baseUrl: String, apiClass: Class<T>, client: OkHttpClient? = null): T {
        if (retrofit != null && retrofit?.baseUrl().toString() == baseUrl) {
            return (api as T)
        }
        retrofit = Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(client ?: okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
        api = retrofit!!.create<T>(apiClass)!!
        return (api as T)
    }

    /**
     * 有基本的使用功能，需要自定义转换器
     */
    fun <T> createService(baseUrl: String, apiClass: Class<T>, builder: ((Retrofit.Builder) -> Unit)? = null): T {
        val retrofitBuilder = Retrofit.Builder()
        retrofitBuilder.baseUrl(baseUrl)
        builder?.invoke(retrofitBuilder)
        return retrofitBuilder.build().create<T>(apiClass)
    }

    /**
     * 通过service发送请求，并回调
     */
    fun <T> sendRequest(request: retrofit2.Call<T>, success: (T) -> Unit, fail: ((Throwable?) -> Unit)? = null) {
        request.enqueue(object : Callback<T> {
            override fun onFailure(call: retrofit2.Call<T>?, t: Throwable?) {
                fail?.invoke(t)
                t?.printStackTrace()
            }

            override fun onResponse(call: retrofit2.Call<T>?, response: Response<T>?) {
                if (response?.body() == null) {
                    fail?.invoke(Throwable("response.body is null"))
                } else {
                    success.invoke(response.body()!!)
                }
            }
        })
    }

    fun <T> sendRequestAsync(request: retrofit2.Call<T>, callback: Callback<T>) {
        request.enqueue(callback)
    }

    fun <T> sendRequestSync(request: retrofit2.Call<T>): Response<T> {
        return request.execute()
    }
}